#include "factory_info.h"
#include "bsp_uart.h"
#include "bsp_cpu.h"

const struct factory_info factory_info __attribute__ ((at(FLASH_FACTORY_INFO_ADDRESS))) = {
	.firmware_version = "V1.0.0",
	.firmware_publish_date = "2025/02/23",
	.firmware_upgrade_flag = 0,
};

// 测试iap，故意让app固件变得更大
const uint8_t test[1] __attribute__ ((at(0x0800F000)));

struct cmds cmds[] = {
	{1, "factory"},					// 获取固件版本
	{2, "upgrade"},					// 固件升级
	{3, "reset"},
};

/****************************************************************************************************
 @brief  从通信接口接收一个字符

 @param  [ byte ] 接收字符

 @return [ true  ] 接收成功						
		 [ false ] 接收超时
****************************************************************************************************/
static bool receive_byte(uint8_t *byte)
{
	int32_t timeout = NAK_TIMEOUT;
	
	while(timeout-- > 0)
	{
		if(uart_get_char(COM1, byte) == true) {
			return true;
		}
	}
	
	return false;
}

/****************************************************************************************************
 @brief  接收并解析上位机命令

 @param  无

 @return 成功返回指令ID
		 失败返回0
****************************************************************************************************/
static int32_t receive_cmd_parse(void)
{
    uint8_t ch;

    uint8_t match_progress[sizeof(cmds) / sizeof(cmds[0])] = {0};

    while(receive_byte(&ch)) 
    {
        bool has_possible_match = false;
        
        for(int i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) 
        {
            if(match_progress[i] == 0xFF) {
				continue;
			}
            
            if(ch == cmds[i].name[match_progress[i]]) 
            {
                match_progress[i]++;
                if(cmds[i].name[match_progress[i]] == '\0') {
                    return cmds[i].id;
                }
                has_possible_match = true;
            } 
            else 
            {
                match_progress[i] = 0xFF;
            }
        }
        
        if(!has_possible_match) {
			break;
		}
    }
    
    return 0; 
}

/****************************************************************************************************
 @brief  处理上位机指令

         1.获取固件版本信息
         2.固件升级

 @param  无

 @return 无
****************************************************************************************************/
void factory_info_handle(void)
{
    printf("Application run.\r\n");
	printf("Version: %s\r\nPublish date: %s\r\nMCU: %s\r\nCore: %s\r\nFreq: %s\r\nFlash szie: %s", 
           factory_info.firmware_version,
           factory_info.firmware_publish_date,
		   "STM32",
		   "ARM Cortex-M3",
		   "72MHz",
		   "64K");

    while(1)
    {
        int32_t cmd_id = receive_cmd_parse();
        
        switch(cmd_id)
        {
            case 1: 
				printf("factory %s;%s", factory_info.firmware_version,
					   factory_info.firmware_publish_date);
                break;
                
            case 2: 
				FLASH_Unlock();
				FLASH_ErasePage(FLASH_FACTORY_INFO_ADDRESS);
				FLASH_Lock();
				ms_delay(500);
				cpu_reset();
                break;

            case 3:
				cpu_reset();
                break;
                
            default:
				break;
        }
    }
}
